﻿using PSE.Framework.Communication.Configuration.Adapters.File.ExcelFile;
using PSE.Framework.Communication.Adapters.File;
using System.IO;
using PSE.Framework.Communication.Configuration.Adapters;
using FileHelpers.DataLink;
using PSE.Framework.Communication.Configuration.Exceptions;
using System;
using PSE.Framework.Communication.Configuration.File;
using PSE.Framework.Communication.Configuration.File.ExcelFile;

namespace PSE.Framework.Communication.Adapters.File.ExcelFile
{
    public class AsyncExcelFileInputAdapter : AsyncFileInputAdapter<ExcelFileInputConfiguration>
    {
        private ExcelStorage _storage = null;
        private bool _fixedType = false;
        private int _rowCount = 0;
        Type _recordType = null;

        public AsyncExcelFileInputAdapter()
        {

        }

        public override void Open(ExcelFileInputConfiguration config, object parameter)
        {
            base.Open(config, parameter);

            // Capturando type
            if (this.Configuration.Actions[0].DeserializedMessageType != null)
            {
                _recordType = this.Configuration.Actions[0].DeserializedMessageType;
                _fixedType = true;
            }
            else if (!string.IsNullOrEmpty(this.Configuration.Actions[0].DeserializedMessageFile))
            {
                _recordType = FileHelpers.RunTime.ClassBuilder.ClassFromXmlFile(this.Configuration.Actions[0].DeserializedMessageFile);
                _fixedType = false;
            }
            else
            {
                throw new InvalidAdapterConfigurationException("DeserializedMessageType and DeserializedMessageFile were not informed", this.Configuration.Name);
            }
        }

        protected override void OpenFile(string fullPath)
        {
            _storage = new ExcelStorage(_recordType, fullPath, this.Configuration.IgnoreFirstRows + 1, 1);
            _storage.SheetName = this.Configuration.SheetName;

            _storage.BeginExtractRecords();

            _rowCount = 0;
        }

        protected override object ReadRecord()
        {
            // Não pode ler as primeiras linhas a serem ignoradas, para não dar erro
            if (_rowCount < this.Configuration.IgnoreFirstRows)
            {
                _rowCount++;
                return null;
            }

            _rowCount++;

            if (_fixedType)
            {
                return _storage.ExtractNextRecord();
            }
            else
            {
                return _storage.ExtractNextRecordAsDictionary();
            }
        }

        protected override object Deserialize(object message, string action)
        {
            return message;
        }

        protected override void CloseFile()
        {
            if (_storage != null)
            {
                _storage.EndExtractRecords();
                _storage = null;
            }
            _fixedType = false;
            _rowCount = 0;
            _recordType = null;
        }

        protected override int GetFileRowCount()
        {
            return _storage.GetRowCount();
        }

    }//end ExcelFileInputAdapter

}